package com.imon.web.codesphere.resources;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Component;

import com.imon.web.codesphere.data.RevisionInfo;

@Path("/svnlog")
@Component
public class SvnLogResource extends ResourceBase {

	private static final Log LOG = LogFactory.getLog(SvnLogResource.class);
	private static int PAGESIZE = 10;

	@GET
	@Produces(MediaType.APPLICATION_JSON)
	public Response loadAll() {
		LOG.debug("loadAll");
		final Collection<RevisionInfo> allRevisions = getDatabase().loadAll(RevisionInfo.class, "-revision");
		LOG.debug(String.format("Total revisions: %d", allRevisions.size()));
		return Response.ok(getJsonParser().getJson(allRevisions)).build();
	}

	@GET
	@Path("/search/{searchtext}")
	@Produces(MediaType.APPLICATION_JSON)
	public Response searchLog(@PathParam("searchtext") final String searchText,
			@QueryParam("repo") final String repoPath) {
		LOG.debug(String.format("searchLog(%s, %s)", searchText, repoPath));

		Map<String, Object> criteria = null;

		final Pattern pattern = Pattern.compile("r(\\d.*)");

		final Matcher matcher = pattern.matcher(searchText);

		if (matcher.find()) {
			final String revision = matcher.group(1);

			criteria = new HashMap<String, Object>() {
				{
					put("repositoryUrl =", repoPath);
					put("revision =", Integer.valueOf(revision));
				}
			};
		} else {
			criteria = new HashMap<String, Object>() {
				{
					put("repositoryUrl =", repoPath);
					put("revisionChanges.path =", Pattern.compile("^.*" + searchText));
				}
			};
		}

		final Collection<RevisionInfo> revisions = getDatabase().loadAll(RevisionInfo.class, criteria, "-revision");

		LOG.debug("Revisions:" + revisions.size());

		return Response.ok(getJsonParser().getJson(revisions)).build();
	}

	@GET
	@Path("/count")
	@Produces(MediaType.TEXT_PLAIN)
	public Response countAllRecords(@QueryParam("repo") final String repoPath) {
		LOG.debug(String.format("countAllRecords(%s)", repoPath));

		if (StringUtils.isEmpty(repoPath))
			return Response.ok("0/0").build();

		final long totalRecords = getDatabase().count(RevisionInfo.class, "repositoryUrl", repoPath);
		return Response.ok(String.format("%s/%s", totalRecords, PAGESIZE)).build();
	}

	@GET
	@Path("/{pagenumber}")
	@Produces(MediaType.APPLICATION_JSON)
	public Response loadPage(@PathParam("pagenumber") final int pageNumber, @QueryParam("repo") final String repoPath) {
		LOG.debug(String.format("loadPage(%d, %s)", pageNumber, repoPath));

		if (pageNumber < 1)
			return Response.ok().build();

		final int offset = PAGESIZE * (pageNumber - 1);
		final int limit = PAGESIZE;

		final Map<String, Object> criteria = new HashMap<String, Object>() {
			{
				put("repositoryUrl =", repoPath);
			}
		};

		final Collection<RevisionInfo> revisions = getDatabase().loadAll(RevisionInfo.class, criteria, "-revision",
				offset, limit);

		return Response.ok(getJsonParser().getJson(revisions)).build();
	}
}
